#ifndef __GLF_CORE_ITHREAD_H_INCLUDED__
#define __GLF_CORE_ITHREAD_H_INCLUDED__

#include <glf/core/thread.h>
#include <glf/core/spinLock.h>
#include <glf/core/genericRecursiveMutex.h>
#include <glf/core/threadTraits.h>

#if GLF_COMPILER_SNC
#   pragma diag_push
#   pragma diag_suppress=187
#endif

namespace glf {

struct ThreadMgr : private NonCopyable {
	GenericRecursiveMutex<SpinLock> mSpinLock;
	typedef GenericRecursiveMutex<SpinLock>::LockScope LockScope;

	ThreadId mMainThreadId;
	Thread mMainThread;

	Thread* mThreads[GLF_MAX_THREADS];
	uint mNumThreads;

	Thread* mMirrorThreads[GLF_MAX_THREADS];
	uint mNumMirrorThreads;

	struct StartExitHandlers {
		void (*mOnStart)(void*);
		void (*mOnExit)(void*);
		void* mArg;
	};

	SpinLock mStartExitHandlersMutex;
	StartExitHandlers mStartExitHandlers[16];

	ThreadMgr();
	~ThreadMgr();

	void Init();
	void DeInit();

	Thread& GetCurrent();

	Thread* AddMirrorThreads(Thread* thread);

	void Sleep(uint ms) {
		GetCurrent()._Sleep(ms);
	}

	void Add(Thread* t);
	void Remove(Thread* t);

	int AddStartExitHandlers(void (*onStart)(void*), void (*onExit)(void*), void* arg);
	void* RemoveStartExitHandlers(unsigned int id);

	void OnStartThread();
	void OnExitThread();
};

}
#if GLF_COMPILER_SNC
#   pragma diag_pop
#endif

#endif
